package org.jeecg.modules.util;

import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.demo.allvipcard.entity.AllVipcard;
import org.jeecg.modules.demo.allvipcard.service.IAllVipcardService;
import org.springframework.beans.support.PagedListHolder;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.math.BigDecimal;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;

@Slf4j
public class ToolsUtils {
    /**
     * 计算list中某一属性的合计值
     */
    public static BigDecimal getSumField(List<Map<String, Object>> list, String field) {
        return list.stream().map(map -> map.get(field) == null || !(map.get(field) instanceof BigDecimal) ? BigDecimal.ZERO : (BigDecimal) map.get(field)).reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
    }

    /**
     * 小数保留两位小数（-0.01 < number < 0.01的保留4位小数）
     */
    public static String formatNumber(Object number) {
        if (number instanceof BigDecimal){
            // 数字格式化工具（2位小数）
            NumberFormat nf = NumberFormat.getInstance();
            nf.setGroupingUsed(false);
            nf.setMaximumFractionDigits(2);
            nf.setMinimumFractionDigits(2);
            return nf.format(number);
        }
        if (number instanceof Double){
//            int t = (int)(((Double) number).doubleValue() * 100);
//            double scale = getScale(t * 0.01);
            return getScale((double)number)+"";
             //String.valueOf(scale);
        }


        return number.toString();
    }

    //判断是否为数字
    public static boolean isNumeric(Object str) {
        if (str != null && StringUtils.isNotEmpty(str.toString())) {
            try {
                Pattern pattern = Pattern.compile("([1-9]\\d*\\.?\\d*)|(0\\.\\d*[1-9])");
                return pattern.matcher(str.toString()).matches();
            } catch (Exception e) {
                e.getMessage();
                return false;
            }
        } else {
            return false;
        }
    }

    public static int getNumeric(String str) {
        if (str != null && StringUtils.isNotEmpty(str.toString())) {
            try {
                Pattern pattern = Pattern.compile("([1-9]\\d*\\.?\\d*)|(0\\.\\d*[1-9])");
                if (pattern.matcher(str).matches()) {
                    return Integer.parseInt(str);
                }
                return 0;
            } catch (Exception e) {
                e.getMessage();
                return 0;
            }
        } else {
            return 0;
        }
    }

    public static int getNumeric(Object str) {
        if (str != null && StringUtils.isNotEmpty(str.toString())) {
            try {
                Pattern pattern = Pattern.compile("([1-9]\\d*\\.?\\d*)|(0\\.\\d*[1-9])");
                if (pattern.matcher(String.valueOf(str)).matches()) {
                    return Integer.parseInt(String.valueOf(str));
                }
                return 0;
            } catch (Exception e) {
                e.getMessage();
                return 0;
            }
        } else {
            return 0;
        }
    }
    public static Double getNumerics(String str) {
        if (str != null && StringUtils.isNotEmpty(str.toString())) {
            try {
                Pattern pattern = Pattern.compile("([1-9]\\d*\\.?\\d*)|(0\\.\\d*[1-9])");
                if (pattern.matcher(str).matches()) {
                    return Double.parseDouble(str);
                }
                return 0.0;
            } catch (Exception e) {
                e.getMessage();
                return 0.0;
            }
        } else {
            return 0.0;
        }
    }
    public static double getNumerics(Object str) {
        if (str != null && StringUtils.isNotEmpty(str.toString())) {
            try {
                Pattern pattern = Pattern.compile("([1-9]\\d*\\.?\\d*)|(0\\.\\d*[1-9])");
                if (pattern.matcher(String.valueOf(str)).matches()) {
                    return Double.parseDouble(String.valueOf(str));
                }
                return 0.0;
            } catch (Exception e) {
                e.getMessage();
                return 0.0;
            }
        } else {
            return 0.0;
        }
    }
    //实体类转map
    public static Map<String, Object> objectToMap(Object obj) {
        Map<String, Object> map = new HashMap<String, Object>();
        if (obj == null)
            return map;

        BeanInfo beanInfo = null;
        try {
            beanInfo = Introspector.getBeanInfo(obj.getClass());
        } catch (IntrospectionException e) {
            log.error("[beanInfo = {}]自省过程发生异常", beanInfo, e);
        }

        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
        for (PropertyDescriptor property : propertyDescriptors) {
            String key = property.getName();
            if (key.compareToIgnoreCase("class") == 0) {
                continue;
            }
            Method getter = property.getReadMethod();
            Object value = null;
            try {
                value = getter != null ? getter.invoke(obj) : null;
            } catch (Exception e) {
                log.error("[value = {}]object转map时发生异常", value, e);
            }
            map.put(key, value);
        }

        return map;
    }

    public static <T> T mapToObject(Map<String, Object> map, Class<T> clz) {

        T obj = null;
        try {
            obj = clz.newInstance();
        } catch (InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }
        Field[] declaredFields = obj.getClass().getDeclaredFields();
        for (Field field : declaredFields) {
            int mod = field.getModifiers();
            if (Modifier.isStatic(mod) || Modifier.isFinal(mod)) {
                continue;
            }
            field.setAccessible(true);
            try {
                field.set(obj, map.get(field.getName()));
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return obj;
    }

    public static String setToTime(int time) {
        String timeStr = null;
        int hour = 0;
        int minute = 0;
        int second = 0;
        if (time <= 0)
            return "00:00:00";
        else {
            minute = time / 60;
            if (minute < 60) {
                second = time % 60;
                timeStr = "00:" + unitFormat(minute) + ":" + unitFormat(second);
            } else {
                hour = minute / 60;
                if (hour > 99)
                    return "99:59:59";
                minute = minute % 60;
                second = time - hour * 3600 - minute * 60;
                timeStr = unitFormat(hour) + ":" + unitFormat(minute) + ":" + unitFormat(second);
            }
        }
        return timeStr;
    }

    private static String unitFormat(int i) {
        String retStr = null;
        if (i >= 0 && i < 10)
            retStr = "0" + Integer.toString(i);
        else
            retStr = "" + i;
        return retStr;
    }

    public static String getLastDays(String days, int last) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Calendar c = Calendar.getInstance();
            c.setTime(sdf.parse(days));
            c.add(Calendar.DATE, last);
            Date date = c.getTime();
            return sdf.format(date);
        } catch (ParseException e) {
            e.printStackTrace();
            return "";
        }
    }

    public static String getLastDay(int last) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        c.add(Calendar.DATE, last);
        Date date = c.getTime();
        return sdf.format(date);
    }

    public static String getYesterDay() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        c.add(Calendar.DATE, -1);
        Date date = c.getTime();
        return sdf.format(date);
    }

    public static String getBeforeYesterDay() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        c.add(Calendar.DATE, -2);
        Date date = c.getTime();
        return sdf.format(date);
    }

    public static String getBeforeYear() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        c.add(Calendar.DATE, -365);
        Date date = c.getTime();
        return sdf.format(date);
    }

    public static Page<Map<String, Object>> getpage(List<Map<String, Object>> listMap, Integer pageNo, Integer pageSize) {
        Page<Map<String, Object>> page = new Page<>(pageNo, pageSize);
        Integer count = listMap.size();
        PagedListHolder<Map<String, Object>> pagedListHolder = new PagedListHolder<>(listMap);
        pagedListHolder.setPageSize(pageSize);
        pagedListHolder.setPage(pageNo - 1);

        page.setTotal(count);
        page.setPages(count % pageSize == 0 ? count / pageSize : count / pageSize + 1);
        page.setCurrent(pageNo);
        page.setSize(pageSize);
        page.setRecords(pagedListHolder.getPageList());
        return page;
    }

    public static String bigDouble(double d) {
        String str = String.valueOf(d);
        if (str.contains("E")) {
            String lenStr = str.substring(str.indexOf("E") + 1);
            if (isNumeric(lenStr)) {
                StringBuilder buf = new StringBuilder();
                int len = Integer.parseInt(lenStr);
                for (int i = 0; i < str.length(); i++) {
                    String s = str.substring(i, i + 1);
                    if (s.equals("E")) {
                        break;
                    }
                    if (isNumeric(s)) {
                        buf.append(s);
                        if (i == (len - 1)) {
                            buf.append(".");
                        }
                    }
                }
                return buf.toString();
            }
        }
        return str;
    }

    public static String getBillNo(String preStr) {
        Date date = new Date(System.currentTimeMillis());
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        Random random = new Random();
        int rInt = random.nextInt(9000) + 1000;
        String str = preStr + format.format(date) + rInt;
        return str;
    }

    public static String getPatternPayment(String patternPayment) {
        if(patternPayment.equals("01")){
            return "扫码支付";
        }
        if(patternPayment.equals("02")){
            return "现金支付";
        }
        if(patternPayment.equals("03")){
            return "微信支付";
        }
        if(patternPayment.equals("04")){
            return "支付宝记账";
        }
        if(patternPayment.equals("05")){
            return "微信记账";
        }
        if(patternPayment.equals("06")){
            return "会员余额支付";
        }
        if(patternPayment.equals("07")){
            return "股本余额支付";
        }
        return "";
    }

    public static double getScale(double d) {
        try {
            BigDecimal bg = new BigDecimal(d);
            return bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
        }catch (Exception e){
            e.getMessage();
            return 0;
        }
    }

    public static double getScale(BigDecimal b) {
        try {
            return b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
        }catch (Exception e){
            e.getMessage();
            return 0;
        }
    }

    /**
     * 获取本月第一天
     * @return
     */
    public  static Date getmindate(){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));

        return calendar.getTime();
    }

    /**
     * 获取本月最后一天
     * @return
     */
    public  static Date getmaxdate(){
        Calendar calendar2 = Calendar.getInstance();
        calendar2.setTime(new Date());
        calendar2.set(Calendar.DAY_OF_MONTH, calendar2.getActualMaximum(Calendar.DAY_OF_MONTH));
        return calendar2.getTime();
    }

    public static String getString(Object str) {
        return str == null?"":String.valueOf(str);
    }
    /**
     * 将JSONArray对象转换成List集合
     *
     * @param json
     * @return
     * @see
     */
    public static Object translate(JSONArray json) {
        List<Object> list = new ArrayList<Object>();
        for (Object o : json) {
            if (o instanceof JSONArray)
                list.add(translate((JSONArray) o));
            else
                list.add(o);
        }
        return list;
    }

    /**
     *
     * @param data
     * @param num
     * @return
     */
    public static Double doubleFormat(Double data,Integer num){
        BigDecimal bData = new  BigDecimal(data);
        Double finalData  = bData.setScale(num,BigDecimal.ROUND_HALF_UP).doubleValue();
        return  finalData;
    }

    public static String getUerName(){
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        if (sysUser != null){
            return sysUser.getRealname();
        }
        return  "";
    }


    public static void main(String[] args) {
        System.out.println(doubleFormat(4/3.0,2));
    }
}
